package com.tencreat.service.mall.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.domain.entity.SysUser;
import com.tencreat.common.core.domain.model.LoginUser;
import com.tencreat.common.core.domain.model.ReqIdParam;
import com.tencreat.common.core.domain.model.ReqIdsParam;
import com.tencreat.common.exception.CustomException;
import com.tencreat.common.utils.SecurityUtils;
import com.tencreat.common.utils.StringUtils;
import com.tencreat.common.utils.TenCreatUtil;
import com.tencreat.domain.mall.*;
import com.tencreat.domain.mall.dto.*;
import com.tencreat.domain.mall.vo.*;
import com.tencreat.mapper.mall.MallGoodsMapper;
import com.tencreat.mapper.mall.MallStoreGoodsMapper;
import com.tencreat.service.mall.*;
import com.tencreat.service.system.ISysDeptService;
import com.tencreat.service.system.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 店铺商品基本信息Service业务层处理
 *
 * @author tencreat
 * @date 2021-08-13
 */
@Service
@Slf4j
public class MallStoreGoodsServiceImpl extends ServiceImpl<MallStoreGoodsMapper, MallStoreGoods> implements IMallStoreGoodsService {
    protected final Logger logger = LoggerFactory.getLogger("sys-storeOrderGoods");

    private final IMallAppCategoryService mallAppCategoryService;//类目
    private final IMallCollectService mallCollectService;//收藏
    private final IMallCommentService mallCommentService;//评论
    private final IMallStoreOrderGoodsService mallStoreOrderGoodsService;//店铺订单商品
    private final ISysDeptService sysDeptService;//部门管理

   // private final IMallStoreOrderService mallStoreOrderService;//订单


    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IMallSetmealNormsService mallSetmealNormsService;//店铺商品规格参数

    @Autowired
    private IMallStoreOrderService mallStoreOrderService;

    public MallStoreGoodsServiceImpl(IMallAppCategoryService mallAppCategoryService, IMallCollectService mallCollectService, IMallCommentService mallCommentService, IMallStoreOrderGoodsService mallStoreOrderGoodsService, ISysDeptService sysDeptService) {
        this.mallAppCategoryService = mallAppCategoryService;
        this.mallCollectService = mallCollectService;
        this.mallCommentService = mallCommentService;
        this.mallStoreOrderGoodsService = mallStoreOrderGoodsService;
        this.sysDeptService = sysDeptService;
        //this.mallStoreOrderService=mallStoreOrderService;
    }


    /**
     * 查询店铺商品基本信息
     *
     * @param id 商品基本信息ID
     * @return 商品基本信息
     */
    @Override
    public MallStoreGoods selectMallStoreGoodsById(ReqIdParam id) {
        return baseMapper.selectById(id.getId());
    }

    /**
     * 查询店铺商品基本信息列表
     *
     * @param mallStoreGoods 商品基本信息
     * @return 商品基本信息
     */
    @Override
    public List<MallStoreGoods> selectMallStoreGoodsList(MallStoreGoods mallStoreGoods) {
        return baseMapper.selectList(Wrappers.query(mallStoreGoods));
    }

    /**
     * 新增店铺商品基本信息
     *
     * @param mallStoreGoods 商品基本信息
     * @return 结果
     */
    @Override
    public int insertMallStoreGoods(MallStoreGoods mallStoreGoods) {
        mallStoreGoods.setCreateTime(LocalDateTime.now());
        return baseMapper.insert(mallStoreGoods);
    }

    /**
     * 修改店铺商品基本信息
     *
     * @param mallStoreGoods 商品基本信息
     * @return 结果
     */
    @Override
    public int updateMallStoreGoods(MallStoreGoods mallStoreGoods) {
        mallStoreGoods.setUpdateTime(LocalDateTime.now());
        if (mallStoreGoods.getIsOnSale() != null && mallStoreGoods.getIsOnSale() == 1) {
            mallStoreGoods.setShelfTime(LocalDateTime.now());
        }
        return baseMapper.updateById(mallStoreGoods);
    }

    /**
     * 批量删除店铺商品基本信息
     *
     * @param ids 需要删除的商品基本信息ID
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMallStoreGoodsByIds(ReqIdsParam ids) {
        return baseMapper.deleteBatchIds(ids.getId());
    }

    /**
     * 删除店铺商品基本信息信息
     *
     * @param id 商品基本信息ID
     * @return 结果
     */
    @Override
    public int deleteMallStoreGoodsById(ReqIdParam id) {
        return baseMapper.deleteById(id.getId());
    }


    /**
     * 描述信息  新增店铺商品 店铺商品规格参数
     * @Author yaoruiqi
     * @Date: 2023/10/12 11:25
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertMallStoreGoodsPo(MallShopGoodsAddDTO mallShopGoodsAddDTO) {
        //  新增时 在good中的价格设置为所有规格的最低价
        BigDecimal miniPrice = null;
        BigDecimal inventory = BigDecimal.ZERO;//库存
        MallStoreGoods goods = mallShopGoodsAddDTO.getGoods();
        goods.setGoodsSn(TenCreatUtil.getOrderNo());
        if (goods != null) {
            if (mallShopGoodsAddDTO.getNorms() == null || mallShopGoodsAddDTO.getNorms().size() < 0) {
                throw new CustomException("规格信息不能为空");
            }
            goods.setCreateTime(LocalDateTime.now());
            goods.setPicUrl(JSONObject.parseObject(goods.getGallery(), ArrayList.class).get(0).toString());
            goods.setAuditStatus(1);
            goods.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
            baseMapper.insert(goods);
            List<MallSetmealNorms> norms = mallShopGoodsAddDTO.getNorms();
            for (MallSetmealNorms goodsNorms : norms) {
                inventory = inventory.add(BigDecimal.valueOf(goodsNorms.getInventory()));
                goodsNorms.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
                goodsNorms.setGoodsId(goods.getId());
            }
            mallSetmealNormsService.saveOrUpdateBatch(norms);
        }
/*        if (goods.getMemberDiscount() != null) {
            goods.setSalesDiscount(goods.getMemberDiscount() + "");
        }*/
        goods.setInventory(inventory.longValue());
        goods.setRetailPrice(miniPrice);
        baseMapper.updateById(goods);
        return 1;
    }

    @Override
    public MallStoreGoodsAllVO getInfoGoodsVo(ReqIdParam id) {
        MallStoreGoodsAllVO mallStoreGoodsAllVO = new MallStoreGoodsAllVO();
        MallStoreGoods goods = baseMapper.selectById(id.getId());
        MallShopGoodsDTO mallShopGoodsDTO = new MallShopGoodsDTO();
        if (goods != null) {
            LambdaQueryChainWrapper<MallAppCategory> mallCategoryLambda = mallAppCategoryService.lambdaQuery();
            mallCategoryLambda.eq(MallAppCategory::getId, goods.getCategoryId());
            MallAppCategory child = mallCategoryLambda.one();
            mallCategoryLambda = mallAppCategoryService.lambdaQuery();
            //mallCategoryLambda.eq(MallAppCategory::getId, child.getPid());
            MallAppCategory parent = mallCategoryLambda.one();
            BeanUtils.copyProperties(goods, mallShopGoodsDTO);
            mallShopGoodsDTO.setCategoryId(Arrays.asList(parent.getId(), child.getId()));
        }
        mallStoreGoodsAllVO.setMallShopGoodsDTO(mallShopGoodsDTO);

        return mallStoreGoodsAllVO;
    }


    @Override
    public IPage<MallStoreTableVO> pageTableVo(MallShopGoodsDTO goods) {
        MallStoreGoods mallGoods = new MallStoreGoods();
        BeanUtils.copyProperties(goods, mallGoods);
        IPage<MallStoreGoods> page = new Page<>(mallGoods.getPageNum(), mallGoods.getPageSize());
        QueryWrapper<MallStoreGoods> query = null;
        mallGoods.setName(null);
        if (StringUtils.isNotEmpty(goods.getUserName())) {
            SysUser sysUser = sysUserService.selectByNickName(goods.getUserName());
            if (sysUser == null) {
                return new Page<>(mallGoods.getPageNum(), mallGoods.getPageSize());
            }
            mallGoods.setUserId(sysUser.getUserId());
        }
        query = Wrappers.query(mallGoods);
        if (StringUtils.isNotEmpty(goods.getName())) {
            query.like("name", goods.getName());
        }
        if (goods.getCategory() != null) {
            query.eq("category_id", goods.getCategory());
        }
        if (goods.getStartTime() != null && goods.getEndTime() != null) {
            query.between("create_time", goods.getStartTime(), goods.getEndTime());
        }
        if (goods.getMin() != null && goods.getMax() != null) {
            query.between("retail_price", goods.getMin(), goods.getMax());
        }
        if (StringUtils.isNotEmpty(goods.getSortStr()) && StringUtils.isNotEmpty(goods.getSortDesc())){
            if ("descending".equals(goods.getSortDesc())){
                query.orderByDesc(goods.getSortStr());
            }else {
                query.orderByAsc(goods.getSortStr());
            }
        }else {
            query.orderByDesc("top").orderByAsc("sort").orderByDesc("create_time");
        }

        query.eq("audit_status", 1);

        page = this.page(page, query);
        return page.convert(item -> {
            MallStoreTableVO vo = new MallStoreTableVO();
            LambdaQueryChainWrapper<MallAppCategory> mallCategoryLam = mallAppCategoryService.lambdaQuery();
            MallAppCategory mallCategory = mallCategoryLam.eq(MallAppCategory::getId, item.getCategoryId()).one();
/*            if (mallCategory != null) {
                vo.setTwoLevel(mallCategory.getName());
                //mallCategory = mallAppCategoryService.lambdaQuery().eq(MallAppCategory::getId, mallCategory.getPid()).one();
                if (mallCategory != null) {
                    vo.setOneLevel(mallCategory.getName());
                }
            }*/
            if (null != item.getUserId()) {
                SysUser sysUser = sysUserService.selectUserById(item.getUserId());
                if (sysUser != null && sysUser.getNickName() != null) {
                    vo.setUserName(sysUser.getNickName());
                }
            }
            List<MallSetmealNorms> list = mallSetmealNormsService.lambdaQuery().eq(MallSetmealNorms::getGoodsId, item.getId()).list();
            long sum = list.stream().map(MallSetmealNorms::getInventory).collect(Collectors.toList()).stream().mapToLong(Long::longValue).sum();


            item.setRetailPrice(list.get(0).getRetailPrice());
            //item.setSupplyPrice(list.get(0).getSupplyPrice());
            item.setInventory(sum);
            BeanUtils.copyProperties(item, vo);
            //vo.setDeductPrice(list.get(0).getDeductPrice());

            return vo;
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateMallStoreGoodsPo(MallShopGoodsAddDTO mallShopGoodsAddDTO) {
        MallStoreGoods goods = mallShopGoodsAddDTO.getGoods();
        if (goods.getId() == null) {
            return 0;
        }
        if (mallShopGoodsAddDTO.getNorms() == null || mallShopGoodsAddDTO.getNorms().size() < 0) {
            throw new CustomException("规格信息不能为空");
        }
        //BigDecimal miniPrice = null;
        BigDecimal inventory = BigDecimal.ZERO;
        List<MallSetmealNorms> norms = mallShopGoodsAddDTO.getNorms();
        for (MallSetmealNorms goodsNorms : norms) {
            inventory = inventory.add(BigDecimal.valueOf(goodsNorms.getInventory()));
            goodsNorms.setGoodsId(goods.getId());
            goodsNorms.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
            //goodsNorms.setTenantId(null);
        }
        goods.setInventory(inventory.longValue());
        baseMapper.updateById(goods);
        mallSetmealNormsService.saveOrUpdateBatch(norms);

        return 1;
    }

    /**
     * 描述信息  店铺搜索功能
     * @Author yaoruiqi
     * @Date: 2023/10/09 05:04
     */
    @Override
    @Transactional
    public IPage<MallStoreGoodsListVO> apiList(MallStoreGoodsSearchDTO mallStoreGoodsSearchDTO) {
        IPage<MallStoreGoods> mallStoreGoodsPage = new Page<>(mallStoreGoodsSearchDTO.getPageNum(), mallStoreGoodsSearchDTO.getPageSize());

        IPage<MallStoreGoods> page = baseMapper.getApiList(mallStoreGoodsSearchDTO, mallStoreGoodsPage);

        return page.convert(item -> {
            MallStoreGoodsListVO mallStoreGoodsListVO = new MallStoreGoodsListVO();
            mallStoreGoodsListVO.setId(item.getId());
            mallStoreGoodsListVO.setSubTitle(item.getBrief());
            mallStoreGoodsListVO.setCoverImg(item.getPicUrl());
            //mallGoodsListVO.setContributionNum(item.getContributionNum().intValue());
            mallStoreGoodsListVO.setTitle(item.getName());
            mallStoreGoodsListVO.setPrice(item.getRetailPrice());
/*            if (!item.getSalesDiscount().equals("10")) {
                mallGoodsListVO.setMemberPrice(TenCreatUtil.discount(item.getRetailPrice(), item.getSalesDiscount()));
            }*/
            //mallGoodsListVO.setSalesDiscount(item.getSalesDiscount());
            mallStoreGoodsListVO.setExpectCommoditySales((item.getExpectCommoditySales() == null ? BigDecimal.ZERO : item.getExpectCommoditySales()).intValue());
            mallStoreGoodsListVO.setCommoditySales((item.getCommoditySales() == null ? BigDecimal.ZERO : item.getCommoditySales()).intValue());
           // mallStoreGoodsListVO.setLogisticsId(item.getLogisticsId());
            mallStoreGoodsListVO.setBrand(item.getBrand());
            mallStoreGoodsListVO.setBurst(item.getBurst());
            mallStoreGoodsListVO.setIsHot(item.getIsHot());
            mallStoreGoodsListVO.setDescribe(item.getDescribe());
            mallStoreGoodsListVO.setCounterPrice(item.getCounterPrice());
            mallStoreGoodsListVO.setInventory(item.getInventory());

            return mallStoreGoodsListVO;
        });
    }

    /**
     * 描述信息  店铺商品详情
     * @Author yaoruiqi
     * @Date: 2023/10/12 05:49
     */
    @Override
    public ResStoreGoodsDetailVO queryInfoByGoodsSn(ReqIdParam id, LoginUser loginUser) {
        Optional<MallStoreGoods> mallGoods = this.lambdaQuery().eq(MallStoreGoods::getId, id.getId()).oneOpt();
        ResStoreGoodsDetailVO resGoodsDetail = new ResStoreGoodsDetailVO();
        BeanUtils.copyProperties(mallGoods.orElse(new MallStoreGoods()), resGoodsDetail);
        resGoodsDetail.setBought(mallGoods.map(MallStoreGoods::getCommoditySales).orElse(0L));
        Optional<MallCollect> mallCollect = mallCollectService
                .lambdaQuery()
                .eq(MallCollect::getUserId, loginUser.getAccountLogin().getId())
                .oneOpt();
        resGoodsDetail.setCollect(mallCollect.isPresent());
        Integer evaluateCount = mallCommentService
                .lambdaQuery()
                .eq(MallComment::getGoodsId, resGoodsDetail.getId())
                .eq(MallComment::getType, 0)
                .count();
        resGoodsDetail.setEvaluate(evaluateCount);
        //resGoodsDetail.setPostage("包邮");

        return resGoodsDetail;
    }

    /**
     * 描述信息  店铺商品详情 app查看商品
     * @Author yaoruiqi
     * @Date: 2023/10/12 06:22
     */
    @Override
    public MallStoreGoodsDetailsVO goodInfoById(ReqIdParam idParam) {
        MallStoreGoodsDetailsVO vo = new MallStoreGoodsDetailsVO();
        MallStoreGoods one = lambdaQuery().eq(MallStoreGoods::getId, idParam.getId()).one();
        BeanUtils.copyProperties(one, vo);

        List<MallSetmealNorms> norms = mallSetmealNormsService.list(new QueryWrapper<MallSetmealNorms>().eq("goods_id", one.getId()).orderByAsc("retail_price"));
        vo.setNorms(norms);
        vo.setRetailPrice(one.getRetailPrice());
        //商品宣传图片列表
        List<String> imgList = new ArrayList<>();
        if (StringUtils.isNotEmpty(one.getVideoUrl())) {
            imgList.add(one.getVideoUrl());
        }
        List<String> gallery = JSONObject.parseObject(one.getGallery(), ArrayList.class);
        imgList.addAll(gallery);
        vo.setGallerys(imgList);
        //商品评论
        List<MallStoreOrderGoods> mallStoreOrderGoodsList = mallStoreOrderGoodsService.list(new QueryWrapper<MallStoreOrderGoods>().eq("goods_sn", one.getGoodsSn()));
        List<MallComment> mallComments = new ArrayList<>();
        for (MallStoreOrderGoods mallStoreOrderGoods : mallStoreOrderGoodsList) {
            if (mallStoreOrderGoods.getComment() > 0) {
                List<MallComment> comments = mallCommentService.list(new QueryWrapper<MallComment>().eq("order_sn", mallStoreOrderGoods.getOrderSn()).eq("is_hide", 0));
                mallComments.addAll(comments);
            }
        }
        vo.setComments(mallComments);

        //购买人数
        Integer buyers = mallStoreOrderService.buyers(one.getId());
        vo.setBuyers(buyers);
        return vo;
    }

    @Override
    public HttpResult<List<MallStoreGoods>> selectNewGoods(MallStoreGoods mallStoreGoods) {
        return HttpResult.ok(baseMapper.selectOrderList(mallStoreGoods));
    }

    @Override
    public void audit(MallGoodsAuditDTO dto) {
        String key = "goods_audit_" + dto.getId();
        RLock lock = redissonClient.getLock(key);
        lock.lock();
        try {
            MallStoreGoods mallStoreGoods = getById(dto.getId());
            if (mallStoreGoods == null || mallStoreGoods.getAuditStatus() != 0) {
                throw new CustomException("该条数据已被审核或失效，请刷新后重试！");
            }
            // 审核通过
            if (dto.getStatus() == 1) {
                lambdaUpdate().eq(MallStoreGoods::getId, dto.getId())
                        .set(MallStoreGoods::getAuditStatus, 1)
                        .set(MallStoreGoods::getAuditOpinion, dto.getAuditOpinion())
                        .set(MallStoreGoods::getIsOnSale, 1)
                        .update();
            }
            // 驳回
            else {
                lambdaUpdate().eq(MallStoreGoods::getId, dto.getId())
                        .set(MallStoreGoods::getAuditStatus, 2)
                        .update();
            }
        } catch (Exception e) {
            throw e;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public List<MallStoreGoods> getByOrderSn(String orderSn) {
        return baseMapper.getByOrderSn(orderSn);
    }

    @Override
    public HashMap<String, BigDecimal> getGoodPrice(GoodsVO good) {
        return baseMapper.getGoodPrice(good.getGoodsId(), good.getNormsId());
    }

    @Override
    public List<Integer> queryCount(){
        // 上架中数量
        Integer count = lambdaQuery().eq(MallStoreGoods::getIsOnSale, 1).eq(MallStoreGoods::getAuditStatus, 1).count();
        // 下架数量
        Integer lowerCount = lambdaQuery().eq(MallStoreGoods::getIsOnSale, 0).eq(MallStoreGoods::getAuditStatus, 1).count();
        // 总数量
        int totalCount = (count != null ? count : 0) + (lowerCount != null ? lowerCount : 0);

        List<Integer> counts = new ArrayList<>();
        counts.add(totalCount);
        counts.add(count);
        counts.add(lowerCount);

        return counts;
    }

    /****
     * 上升
     * @param mallStoreGoods
     * @return
     */
    @Override
    public boolean reSortOrderReduce(MallStoreGoods mallStoreGoods) {
        MallStoreGoods one = lambdaQuery().eq(MallStoreGoods::getId, mallStoreGoods.getId()).one();
        one.setSort(one.getSort() -1);
        updateById(one);

        return true;
    }
    /****
     * 下降
     * @param mallStoreGoods
     * @return
     */
    @Override
    public boolean reSortOrderPlus(MallStoreGoods mallStoreGoods) {
        MallStoreGoods one = lambdaQuery().eq(MallStoreGoods::getId, mallStoreGoods.getId()).one();
        one.setSort(one.getSort() +1);
        updateById(one);

        return true;
    }
}
